#region File Description
//-----------------------------------------------------------------------------
// TerrainProcessor.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;

#endregion

namespace TerrainImageProcessor
{
    /// <summary>
    /// Custom content processor for creating terrain meshes. Given an
    /// input heightfield texture, this processor uses the MeshBuilder
    /// class to programatically generate terrain geometry.
    /// </summary>
    [ContentProcessor]
    public class TerrainImageProcessor : ContentProcessor<Texture2DContent, ModelContent>
    {
        public override ModelContent Process(Texture2DContent input, ContentProcessorContext context)
        {
            ModelContent model = null;
            MeshBuilder meshBuilder = MeshBuilder.StartMesh("heightMap");

            // Convert the input to standard Color format, for ease of processing.
            input.ConvertBitmapType(typeof(PixelBitmapContent<float>));

            PixelBitmapContent<float> imageContent = (PixelBitmapContent<float>)input.Mipmaps[0];

            // Loop through image data and create vertices
            // Create the vertices.
            for (int y = 0; y < imageContent.Height; y++)
            {
                for (int x = 0; x < imageContent.Width; x++)
                {
                    Vector3 position;

                    position.X = x;
                    position.Z = y;

                    position.Y = imageContent.GetPixel(x, y) * 20.0f;

                    meshBuilder.CreatePosition(position);
                }
            }

            // Create the triangles
            for (int y = 0; y < imageContent.Height - 1; y++)
            {
                for (int x = 0; x < imageContent.Width - 1; x++)
                {
                    meshBuilder.AddTriangleVertex(x + (y * imageContent.Width));
                    meshBuilder.AddTriangleVertex((x + 1) + (y * imageContent.Width));
                    meshBuilder.AddTriangleVertex((x + 1) + ((y + 1) * imageContent.Width));

                    meshBuilder.AddTriangleVertex(x + y * imageContent.Width);
                    meshBuilder.AddTriangleVertex((x + 1) + ((y + 1) * imageContent.Width));
                    meshBuilder.AddTriangleVertex(x + ((y + 1) * imageContent.Width));
                }
            }

            MeshContent heightMapMesh = meshBuilder.FinishMesh();
            MeshHelper.CalculateNormals(heightMapMesh, true);
            model = context.Convert<MeshContent, ModelContent>(heightMapMesh, "ModelProcessor");

            return model;
        }
    }
}
